import threading
import utils
import re
import random
import time
import os
from email.utils import formatdate

from login import use_default_login
import tasks


def mime(img_type):
    if img_type == 'JPEG':
        return 'image/jpeg'
    elif img_type == 'PNG':
        return 'image/png'
    elif img_type == 'GIF':
        return 'image/gif'
    else:
        return 'image/jpeg'


class WeChatInfrastructureEditor(utils.WeChatClient):

    def setting_page_url(self):
        return '{}/cgi-bin/settingpage?t=setting/index&action=index&token={}&lang=zh_CN'.format(self.url, self.token)

    def safe_header(self, referer, ajax=True):
        headers = {
            "Accept": "application/json, text/javascript, */*; q=0.01",
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
            "Host": "mp.weixin.qq.com",
            "Origin": self.url,
            "Referer": referer,
        }
        if ajax:
            headers['X-Requested-With'] = "XMLHttpRequest"
        return headers

    def check_resp(self, ret, action):
        if ret['base_resp']['ret'] == 0:
            self.log_line(action + '成功')
            return True
        else:
            self.log_err('错误：' + ret['base_resp']['err_msg'])
            return False

    def update_intro(self, intro):
        if intro:
            refer_url = self.setting_page_url()
            resp = self.session.get(refer_url, headers=self.safe_header(self.index_url)).content.decode('utf-8')
            forbid_edit = re.search('本月功能介绍修改次数已达(\d+)次', resp, re.MULTILINE)
            if forbid_edit:
                self.log_err(forbid_edit.group(0))
                return False
            resp = self.session.post('{}/cgi-bin/setuserinfo?action=intro&t=ajax-response&token={}&lang=zh_CN'.format(
                self.url, self.token), {
                "token": self.token, "lang": "zh_CN", "f": "json", "ajax": 1,
                "random": random.random(), "intro": intro}, headers=self.safe_header(refer_url))
            try:
                return self.check_resp(resp.json(), '修改简介')
            except ValueError:
                print(resp.content)
            self.log_err('修改简介失败')
            return False

    def update_avatar(self, avatar):
        if avatar:
            refer_url = self.setting_page_url()
            resp = self.session.get(refer_url).content.decode('utf-8')
            forbid_edit = re.search('本月头像修改次数已达(\d+)次', resp, re.MULTILINE)
            if forbid_edit:
                self.log_err(forbid_edit.group(0))
                return False
            ticket_id = re.search('user_name:"([^"]+)",', resp, re.MULTILINE).group(1)
            ticket = re.search('ticket:"([^"]+)",', resp, re.MULTILINE).group(1)
            with open(avatar['name'], 'rb') as image:
                mime_type = mime(avatar['type'])
                file = {'file': (avatar['name'], image, mime_type)}
                upload = self.session.post(
                    '{}/cgi-bin/filetransfer?action=preview&f=json&ticket_id={}&ticket={}&svr_time={}&token={}'
                    '&lang=zh_CN&seq=1'.format(self.url, ticket_id, ticket, int(time.time()), self.token),
                    {"id": "WU_FILE_0", "name": os.path.basename(avatar['name']), "type": mime_type,
                     "lastModifiedDate": formatdate(localtime=True), "size": avatar['size']}, files=file,
                    headers={"Referer": refer_url}
                )
                try:
                    ret = upload.json()
                    if self.check_resp(ret, '更新头像(上传)') and 'content' in ret:
                        self.crop_avatar(ret['content'], avatar['crop'])
                except ValueError:
                    print(resp.content)
                    self.log_err('上传头像失败')
                    return False

    def crop_avatar(self, fid, crop):
        crop['token'] = self.token
        crop['lang'] = 'zh_CN'
        crop['f'] = 'json'
        crop['ajax'] = 1
        crop['random'] = random.random()
        crop['fid'] = fid
        resp = self.session.post('{}/misc/cropimg?t=ajax-response&token={}&lang=zh_CN'.format(
            self.url, self.token), crop, headers=self.safe_header(self.setting_page_url()))
        try:
            return self.check_resp(resp.json(), '更新头像(确认)')
        except ValueError:
            print(resp.content)
        self.log_err('更新头像失败')
        return False

    def update_auto_reply(self, flag, func_type=4):
        if flag is not None:
            action = '开启' if flag else '关闭'
            refer_url = '{}/advanced/autoreply?action=smartreply&t=ivr/keywords&token={}&lang=zh_CN'.\
                format(self.url, self.token)
            resp = self.session.post('{}/misc/skeyform?form=advancedswitchform'.format(self.url), {
                "flag": str(flag),
                "type": str(func_type),
                "token": self.token,
                "f": "json", "ajax": 1
            }, headers=self.safe_header(refer_url))
            try:
                return self.check_resp(resp.json(), action + '自动回复')
            except ValueError:
                print(resp.content)
            self.log_err('{}自动回复失败'.format(action))
            return False

    def set_search_options(self, is_search):
        if is_search is not None:
            refer_url = '{}/cgi-bin/settingpage?t=setting/function&action=function&token={}&lang=zh_CN'.format(
                self.url, self.token)
            resp = self.session.post('{}/cgi-bin/setuserinfo?t=ajax-response'.format(self.url), {
                "token": self.token,
                "lang": "zh_CN",
                "f": "json",
                "ajax": 1,
                "random": random.random(),
                "action": "search",
                "open": str(is_search)
            }, headers=self.safe_header(refer_url))
            try:
                data = resp.json()
                if data['base_resp']['ret'] == 0:
                    self.log_line('修改搜索成功')
                    return True
                else:
                    self.log_err('错误: ' + data['base_resp']['err_msg'])
                    return False
            except:
                print(resp.content)
            self.log_err('修改搜索失败')
            return False

    def set_menu_status(self, status):
        if status is not None:
            refer_url = '{}/cgi-bin/plugindetails?t=service/profile&pluginid=10007&action=intro&token={}&lang=zh_CN'.format(self.url, self.token)
            resp = self.session.post('{}/misc/skeyform?form=advancedswitchform&lang=zh_CN'.format(self.url), {
                "flag": status,
                "type": 3,
                "token": self.token,
            }, headers=self.safe_header(refer_url))
            try:
                data = resp.json()
                if data['base_resp']['ret'] == 0:
                    self.log_line('修改自定义菜单成功')
                    return True
                else:
                    self.log_err('错误: ' + data['base_resp']['err_msg'])
                    return False
            except:
                print(resp.content)
            self.log_err('修改自定义菜单失败')
            return False


    def set_add_watermark(self, add_watermark):
        try:
            if add_watermark:
                refer_url = '{}/cgi-bin/settingpage?t=setting/function&action=function&token={}&lang=zh_CN'.format(
                    self.url, self.token)
                resp = self.session.get('{0}/misc/watermark?1=1&token={1}&lang=zh_CN&token={1}&lang=zh_CN&f=json&ajax=1&random={2}&action=confirm&type={3}'
                                        .format(self.url,self.token,random.random(), add_watermark))
                try:
                    data = resp.json()
                    if data['base_resp']['ret'] == 0:
                        self.log_line('修改图片水印功能设置成功')
                        return True
                    else:
                        self.log_err('错误: ' + data['base_resp']['err_msg'])
                        return False
                except:
                    print(resp.content)
                self.log_err('修改图片水印功能设置失败')
                return False
        except:
            print("未请求到功能设置页面")
            return False



class EditorThread(threading.Thread):
    def __init__(self, service, task):
        threading.Thread.__init__(self)
        self.service = service
        self.task = task

    def run(self):
        c = WeChatInfrastructureEditor(srv)
        try:
            if not c.enter(self.task['gh_id']):
                return
            c.update_intro(self.task['intro'])
            c.update_avatar(self.task['avatar'])
            c.update_auto_reply(self.task['auto_resp'])
            c.set_search_options(self.task['is_search'])
            c.set_menu_status(self.task['menu_status'])
            c.set_add_watermark(self.task['add_watermark'])
        except ConnectionError:
            pass


if __name__ == '__main__':
    m = tasks.default_manager()
    srv = use_default_login()
    chunks = m.get_task_chunks(5)
    total_chunks = len(chunks)
    current_chunk = 1
    for chunk in chunks:
        print('=第{}批线程开始='.format(current_chunk))
        pool = []
        for task_item in chunk:
            thread = EditorThread(srv, task_item)
            thread.start()
            pool.append(thread)
        for thread in pool:
            thread.join()
        print('=第{}/{}批线程结束='.format(current_chunk, total_chunks))
        current_chunk += 1
    input('运行完毕，然回车键退出')
